package wf.source.hrm.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import wf.source.hrm.cache.CourseTypeCache;
import wf.source.hrm.domain.CourseType;
import wf.source.hrm.mapper.CourseTypeMapper;
import wf.source.hrm.service.ICourseTypeService;
import wf.source.hrm.util.VelocityUtils;

import java.io.Serializable;
import java.util.*;

/**
 * <p>
 * 课程目录 服务实现类
 * </p>
 *
 * @author wangfang
 * @since 2020-06-23
 */
@Service
public class CourseTypeServiceImpl extends ServiceImpl<CourseTypeMapper, CourseType> implements ICourseTypeService {

    @Autowired
    private CourseTypeMapper courseTypeMapper;

    /**
     * 面包屑
     * @param typeId
     * @return
     */
    @Override
    public List<Map<String, Object>> queryTypeCrumbs(Long typeId) {
        //准备
        List<Map<String, Object>> result=new ArrayList<>();
        //1 通过typeid获取Type进而获取path    .01.02.03.
        CourseType courseType = courseTypeMapper.selectById(typeId);
        //获取path
        String path = courseType.getPath();
        System.out.println(path);
        //截取始末2个点
        path= path.substring(1, path.length()- 1);//01.02.03
        //2 通过分隔path得到层次关系数组 【01，02,03】
        String[] patharr = path.split("\\.");
        //3 遍历数组 每个节点最终要生成一个Map，包含当前节点自己及其兄弟
        System.out.println(patharr);
            Map<String,Object> node=new HashMap<>();
        for (String idstr : patharr) {
            System.out.println(idstr+"haha");
            //准备集合
            //3.1当前节点的获取
            CourseType owerCourseType = courseTypeMapper.selectById(Long.valueOf(idstr));
            node.put("owerCourseType",owerCourseType);
            //3.2获取兄弟-查询父亲所有儿子再删除自己
            Long pid = owerCourseType.getPid();
            List<CourseType> children=courseTypeMapper.selectList(new EntityWrapper<CourseType>().eq("pid",pid));
            //先获取迭代器
            Iterator<CourseType> iterator = children.iterator();
            while (iterator.hasNext()){
                CourseType next = iterator.next();
                //一边遍历一边删除自己，要用迭代器
                if(owerCourseType.getId().longValue()==next.getId().longValue()){
                    iterator.remove();
                    break;
                }
            }
            node.put("otherCourseTypes",children);
            result.add(node);
        }
        return result;//一定要改 不然 要出错
    }

    @Override
    public List<CourseType> queryTreeData() {
        /*//方案1：递归 递归获取类型数  不用：以后一个节点就要查询一次儿子 就要发一次sql，节点多了效率低。

        return queryTreeDataByRecursion(0L);*/
        //方案2： 循环方案：一次查询出所有节点，再来组织他们关系 只发了一条sql
        //return queryTreeDataByLoop(0L);
        List<CourseType> treeData=courseTypeCache.loadTreeData();
        if(treeData!=null){
            System.out.println("走的缓存获取数据");
            return treeData;
        }else {//缓存中没有数据 就去数据库查数据 并把数据保存到缓存里
            System.out.println("走的数据库获取数据");
            List<CourseType> courseTypes = queryTreeDataByLoop(0L);
            courseTypeCache.saveTreeData(courseTypes);
            return courseTypes;
        }
    }
    @Autowired
    private CourseTypeCache courseTypeCache;

    //方案2：循环方案：一次查询出所有节点，再来组织他们关系 只发了一条sql
    private List<CourseType> queryTreeDataByLoop(long pid) {
        //准备一个list集合来装 一级的节点
        List<CourseType> result=new ArrayList<>();
        //获取所有的节点
        List<CourseType> courseTypes = courseTypeMapper.selectList(null);
        //提前建立id和类型之间的对应关系
        Map<Long,CourseType> courseTypeMap=new HashMap<>();
        //遍历List集合
        for (CourseType courseType : courseTypes) {
            //把id和课程类型放入map集合里面
            courseTypeMap.put(courseType.getId(),courseType);
        }
        //遍历所有的节点
        for (CourseType courseType : courseTypes) {
            //如果是顶级节点 就将它加入到准备好的result集合中
            if(courseType.getPid().longValue()==pid){
                result.add(courseType);
            }else {//如果不是顶级节点 就将它作为父节点的一个儿子
                //先获取父节点的id
                Long pidTmp=courseType.getPid();
                //从map集合中根据id获取到父课程类型
                CourseType parent = courseTypeMap.get(pidTmp);
                //获取到这个父课程类型的儿子们 并把这个作为儿子加进去
                parent.getChildren().add(courseType);

            }
        }

        return result;
    }


    /**
     * 方案1： 递归获取类型数  以后不用：因为每一个节点就要查询一次儿子 就要发一次sql，节点多效率低。
     * @return
     */
    private List<CourseType> queryTreeDataByRecursion(Long pid) {
        Wrapper<CourseType> wrapper=new EntityWrapper<CourseType>().eq("pid",pid);
        List<CourseType> courseTypes=courseTypeMapper.selectList(wrapper);
        //判断返回的集合 如果集合为空 表示没有儿子就可以返回
        if(courseTypes==null||courseTypes.size()<1){
            return null;
        }
        //如果集合不为空就遍历，并递归调用
        for (CourseType courseType : courseTypes) {
            //获取到课程类型的父id
            Long pid1 = courseType.getPid();
            //再通过父id去查它的儿子集合
            List<CourseType> children = queryTreeDataByRecursion(pid1);
            //再把这个儿子设置到它的儿子里面去
            courseType.setChildren(children);

        }
        //最终都要返回课程类型的集合
        return courseTypes;
    }
    //缓存需要同步更新 删除缓存 以后需要就重新获取数据库的数据
    @Override
    public boolean insert(CourseType entity) {
        super.insert(entity);
        try{
            Thread.sleep(1000);
        }catch (Exception e){
            e.printStackTrace();
        }
        courseTypeCache.del();
        //后台数据发生改变后，我们主页也要改变
        //staticIndex();
        return true;
    }
    //缓存需要同步更新
    @Override
    public boolean deleteById(Serializable id) {
        super.deleteById(id);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        courseTypeCache.del();
        //后台数据发生改变后，我们主页也要改变
        //staticIndex();
        return true;
    }
    //缓存需要同步更新
    @Override
    public boolean updateById(CourseType entity) {
        super.updateById(entity);
        try{
            Thread.sleep(1000);
        }catch (Exception e){
            e.printStackTrace();
        }
        courseTypeCache.del();
        //后台数据发生改变后，我们主页也要改变
        //staticIndex();
        return true;
    }
    //页面静态化
    public void staticIndex(){
        //查询出课程类型数的集合
        List<CourseType> courseTypes = this.queryTreeData();
        //准备map来装参数
        Map<String,Object> param=new HashMap<>();
        param.put("staticRoot","D:\\Javasoftware\\IdeaProjects\\hrm_parent\\hrm_course_parent\\hrm_course_service_2030\\src\\main\\resources\\home");
        param.put("courseTypes",courseTypes);
        VelocityUtils.staticByTemplate(param,"D:\\Javasoftware\\IdeaProjects\\hrm_parent\\hrm_course_parent\\hrm_course_service_2030\\src\\main\\resources\\home\\home.vm",
                "D:\\Javasoftware\\IdeaProjects\\hrm_web_parent\\hrm_web_course\\index.html");
    }

    /**
     *
     */

}
